<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Lz.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'LzVars.php';


class LzDb
{
    static public
    function cfg($cfg = NULL)
    {
        return Lz::def(self::$config, new LzVars())->add($cfg);
    }


    static public
    function inst($name)
    {
        if (isset(self::$inst[$name]))
            return self::$inst[$name];

        if (!preg_match('/^\w+$/', $name))
            throw new LzBadUsage($name);

        if (!isset(self::cfg()->{$name}))
            throw new LzBadUsage($name);

        $db     = self::cfg()->{$name};
        if (empty($db->type))
            throw new LzBadUsage($db->toArr());
        $class  = 'LzDb' . ucfirst(strtolower($db->type));
        $file   = dirname(__FILE__) . Lz::DS . "$class.php";
        if (!is_readable($file))
            throw new LzBadUsage($name);

        require_once $file;
        if (!class_exists($class))
            throw new LzBadUsage($name);

        return self::$inst[$name] = new $class($db);
    }


    protected
    function __construct($cfg)
    {
        $this->cfg  = new LzVars($cfg);

        $this->pdo  = new PDO(
                $this->cfg->dsn,
                $this->cfg->user,
                $this->cfg->pass,
                $this->cfg->options->toArr()
            );
        unset($this->cfg->user, $this->cfg->pass);

        $class  = 'LzSql' . substr(get_class($this), strlen(__CLASS__));
        $file   = dirname(__FILE__) . Lz::DS . "$class.php";
        if (!is_readable($file))
            throw new LzBadUsage($name);

        require_once $file;
        if (!class_exists($class))
            throw new LzBadUsage($name);

        $this->sql  = new $class;

        $this->init();
    }


    public
    function exec($sql, $data = array())
    {
        $sth    = $this->pdo->prepare($sql);
        $sth->execute($data);
        return $sth->fetchAll(PDO::FETCH_ASSOC);
    }


    public
    function query($query)
    {
        if (func_num_args() > 1)
            $query  = func_get_args();

        return $this->exec(
                $this->sql->clear()->query($query),
                $this->sql->data()
            );
    }


    //public
    //function getOne($select)
    //{
    //    return Lz::first($this->getAny($select));
    //}


    public
    function count($select)
    {
        $fields = array('count' => LzSql::raw('COUNT(*)'));
        $select = array_merge($select, compact('fields'));
        return LzArr::first($this->getOne($select));
    }


    protected
    function init()
    {}





    protected   $pdo;
    protected   $sql;
    protected   $cfg;

    static protected    $config;
    static private      $inst;
}

